package io.renren.modules.biz.service.impl;

import io.renren.common.exception.RRException;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.DecimalUtils;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.ProjectConstant;
import io.renren.common.utils.Query;
import io.renren.common.validator.Assert;
import io.renren.modules.biz.dao.BalanceTopupDao;
import io.renren.modules.biz.entity.BalanceDetailEntity;
import io.renren.modules.biz.entity.BalanceTopupEntity;
import io.renren.modules.biz.entity.CountDto;
import io.renren.modules.biz.entity.MemberEntity;
import io.renren.modules.biz.service.BalanceDetailService;
import io.renren.modules.biz.service.BalanceTopupService;
import io.renren.modules.biz.service.MemberService;
import io.renren.modules.sys.service.SysConfigService;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

@Service("balanceTopupService")
public class BalanceTopupServiceImpl extends ServiceImpl<BalanceTopupDao, BalanceTopupEntity> implements BalanceTopupService {

	@Autowired
	private MemberService memberService;

	@Autowired
	private BalanceDetailService balanceDetailService;

	@Autowired
	private SysConfigService sysConfigService;

	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		String mobile = (String) params.get("mobile");
		String memberId = (String) params.get("memberId");
		String authStatus = (String) params.get("authStatus");
		String startDate = (String) params.get("startDate");
		String endDate = (String) params.get("endDate");
		Object type = params.get("type");
		Page<BalanceTopupEntity> page = this.selectPage(
				new Query<BalanceTopupEntity>(params).getPage(),
				new EntityWrapper<BalanceTopupEntity>().eq(StringUtils.isNotBlank(mobile), "mobile", mobile).eq(StringUtils.isNotBlank(memberId), "member_id", memberId).eq(type != null, "type", type).eq(StringUtils.isNotBlank(authStatus), "status", authStatus)
						.ge(StringUtils.isNotBlank(startDate), "create_time", startDate).lt(StringUtils.isNotBlank(endDate), "create_time", endDate));

		return new PageUtils(page);
	}

	@Override
	public void save(BalanceTopupEntity balanceTopup) {
		MemberEntity member = memberService.selectOne(new EntityWrapper<MemberEntity>().eq("id", balanceTopup.getMobile()).or().eq("mobile", balanceTopup.getMobile()));
		Assert.notNull(member, "会员不存在");

		Date now = new Date();
		balanceTopup.setMemberId(member.getId());
		balanceTopup.setMobile(member.getMobile());
		balanceTopup.setStatus(ProjectConstant.AUTH_STATUS_SUCCESS);
		balanceTopup.setType(balanceTopup.getAmount() < 0 ? ProjectConstant.ORDER_TYPE_WITHDRAW : ProjectConstant.ORDER_TYPE_DEPOSIT);
		balanceTopup.setDescription(balanceTopup.getAmount() < 0 ? "系统提现" : "系统充值");
		balanceTopup.setCreateTime(now);
		balanceTopup.setOrderNo(DateUtils.format(new Date(), "yyyyMMddHHmmss") + RandomStringUtils.randomNumeric(6));
		balanceTopup.setPayWay("system");
		this.insert(balanceTopup);

		member.setBalance(DecimalUtils.add(member.getBalance(), balanceTopup.getAmount()));
		member.setUpdateTime(now);
		member.setWithdrawAmountLimit(member.getWithdrawAmountLimit() == 0 ? balanceTopup.getAmount() : DecimalUtils.add(member.getWithdrawAmountLimit(), balanceTopup.getAmount()));
		Assert.isTrue(memberService.updateById(member), "系统繁忙,请重试");

		BalanceDetailEntity detail = new BalanceDetailEntity();
		detail.setMemberId(member.getId());
		detail.setBalanceChange(balanceTopup.getAmount());
		detail.setType(balanceTopup.getType());
		detail.setDescription(balanceTopup.getDescription());
		detail.setCreateTime(now);
		balanceDetailService.insert(detail);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void changeStauts(String type, List<Long> ids) {

		Date now = new Date();
		if (type.equals("TG")) {

			// 通过
			for (Long id : ids) {

				BalanceTopupEntity balanceTopup = this.selectById(id);
				Assert.notNull(balanceTopup, "会员不存在");
				Assert.isTrue(balanceTopup.getStatus() == ProjectConstant.AUTH_STATUS_PENDING, "订单号[" + balanceTopup.getOrderNo() + "]已被审核");

				// 充值
				if (balanceTopup.getType() == ProjectConstant.ORDER_TYPE_DEPOSIT) {

					MemberEntity member = memberService.selectById(balanceTopup.getMemberId());
					member.setBalance(DecimalUtils.add(member.getBalance(), balanceTopup.getAmount()));
					member.setUpdateTime(now);
					member.setWithdrawAmountLimit(member.getWithdrawAmountLimit() == 0 ? balanceTopup.getAmount() : DecimalUtils.add(member.getWithdrawAmountLimit(), balanceTopup.getAmount()));
					Assert.isTrue(memberService.updateById(member), "系统繁忙,请重试");

					balanceTopup.setStatus(ProjectConstant.AUTH_STATUS_SUCCESS);
					balanceTopup.setUpdateTime(now);
					this.updateById(balanceTopup);

					BalanceDetailEntity detail = new BalanceDetailEntity();
					detail.setMemberId(balanceTopup.getMemberId());
					detail.setBalanceChange(balanceTopup.getAmount());
					detail.setType(ProjectConstant.ORDER_TYPE_DEPOSIT);
					detail.setDescription(balanceTopup.getDescription());
					detail.setCreateTime(now);
					balanceDetailService.insert(detail);

				} else {

					MemberEntity member = memberService.selectById(balanceTopup.getMemberId());
					member.setBlockedBalance(DecimalUtils.sub(member.getBlockedBalance(), Math.abs(balanceTopup.getAmount())));
					member.setUpdateTime(now);
					Assert.isTrue(memberService.updateById(member), "系统繁忙,请重试");

					// 更新状态
					balanceTopup.setStatus(ProjectConstant.AUTH_STATUS_SUCCESS);
					balanceTopup.setUpdateTime(now);
					this.updateById(balanceTopup);

					// 更新明细
					BalanceDetailEntity detail = new BalanceDetailEntity();
					detail.setMemberId(balanceTopup.getMemberId());
					detail.setBalanceChange(balanceTopup.getAmount());
					detail.setType(ProjectConstant.ORDER_TYPE_WITHDRAW);
					detail.setDescription(balanceTopup.getDescription());
					detail.setCreateTime(now);
					balanceDetailService.insert(detail);
				}
			}

		} else if (type.equals("WTG")) {

			// 审核拒绝
			for (Long id : ids) {
				BalanceTopupEntity balanceTopup = this.selectById(id);
				Assert.notNull(balanceTopup, "会员不存在");
				Assert.isTrue(balanceTopup.getStatus() == ProjectConstant.AUTH_STATUS_PENDING, "订单号[" + balanceTopup.getOrderNo() + "]已被审核");
				balanceTopup.setStatus(ProjectConstant.AUTH_STATUS_REJECT);
				balanceTopup.setUpdateTime(now);
				this.updateById(balanceTopup);

				// 提现退回冻结金额
				if (balanceTopup.getType() == ProjectConstant.ORDER_TYPE_WITHDRAW) {
					MemberEntity member = memberService.selectById(balanceTopup.getMemberId());
					member.setBalance(DecimalUtils.add(member.getBalance(), Math.abs(balanceTopup.getAmount())));
					member.setBlockedBalance(DecimalUtils.sub(member.getBlockedBalance(), Math.abs(balanceTopup.getAmount())));
					member.setUpdateTime(now);
					Assert.isTrue(memberService.updateById(member), "系统繁忙,请重试");
				}
			}
		} else {
			throw new RRException("操作失败[参数异常]");
		}
	}

	@Override
	public CountDto sumTopupAmount(String memberId, String mobile, String startDate, String endDate, String status) {
		return baseMapper.sumTopupAmount(memberId, mobile, startDate, endDate, status);
	}
}
